package timing.ukulele.storage.controller.minio;

import io.minio.Result;
import io.minio.messages.Item;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import timing.ukulele.common.data.ResponseData;
import timing.ukulele.storage.service.minio.BucketService;
import timing.ukulele.web.controller.BaseController;

import java.util.ArrayList;
import java.util.List;


/**
 * 存储桶相关操作接口
 */
@RestController
@RequestMapping("/bucket")
@Slf4j
@Tag(name = "存储桶相关操作")
public class BucketController extends BaseController {
    private final BucketService bucketService;

    public BucketController(BucketService bucketService) {
        this.bucketService = bucketService;
    }

    @PostMapping("/make")
    @Operation(summary = "创建一个存储桶")
    public ResponseData<Boolean> makeBucket(@Parameter(name = "bucketName", description = "存储桶名称", required = true, in = ParameterIn.QUERY) @RequestParam("bucketName") String bucketName) {
        try {
            this.bucketService.makeBucket(bucketName);
            return successResponse(Boolean.TRUE);
        } catch (Exception e) {
            log.error(e.getMessage());
            return failResponse(Boolean.FALSE, e.getMessage());
        }
    }

    @DeleteMapping("remove")
    @Operation(summary = "删除一个存储桶")
    public ResponseData<Boolean> removeBucket(@Parameter(name = "bucketName", description = "存储桶名称", required = true, in = ParameterIn.QUERY) @RequestParam("bucketName") String bucketName) {
        try {
            this.bucketService.removeBucket(bucketName);
            return successResponse(Boolean.TRUE);
        } catch (Exception e) {
            log.error(e.getMessage());
            return failResponse(Boolean.FALSE, e.getMessage());
        }
    }

    @GetMapping("/list")
    @Operation(summary = "列出某个存储桶中的所有对象")
    public ResponseData<List<Item>> listBuckets(@Parameter(name = "bucketName", description = "存储桶名称", required = true, in = ParameterIn.QUERY) @RequestParam("bucketName") String bucketName,
                                                @Parameter(name = "prefix", description = "对象名称的前缀", in = ParameterIn.QUERY) @RequestParam(value = "prefix", required = false) String prefix,
                                                @Parameter(name = "recursive", description = "是否递归查找，如果是false,就模拟文件夹结构查找", in = ParameterIn.QUERY) @RequestParam(value = "recursive", required = false) Boolean recursive,
                                                @Parameter(name = "useVersion1", description = "如果是true, 使用版本1 REST API", in = ParameterIn.QUERY) @RequestParam(value = "useVersion1", required = false) Boolean useVersion1) {
        try {
            Iterable<Result<Item>> results = this.bucketService.listObjects(bucketName, prefix, recursive, useVersion1);
            List<Item> list = null;
            if (results != null) {
                list = new ArrayList<>();
                for (Result<Item> next : results) {
                    list.add(next.get());
                }
            }
            return successResponse(list);
        } catch (Exception e) {
            log.error(e.getMessage());
            return failResponse(null, e.getMessage());
        }
    }


    @GetMapping("/policy")
    @Operation(summary = "获得指定对象前缀的存储桶策略")
    public ResponseData<String> getBucketPolicy(@Parameter(name = "bucketName", description = "存储桶名称", required = true, in = ParameterIn.QUERY) @RequestParam("bucketName") String bucketName) {
        try {
            String bucketPolicy = this.bucketService.getBucketPolicy(bucketName);
            return successResponse(bucketPolicy);
        } catch (Exception e) {
            log.error(e.getMessage());
            return failResponse(null, e.getMessage());
        }
    }

    @PutMapping("/policy/set")
    @Operation(summary = "给一个存储桶+对象前缀设置策略")
    public ResponseData<Boolean> setBucketPolicy(@Parameter(name = "bucketName", description = "存储桶名称", required = true, in = ParameterIn.QUERY) @RequestParam("bucketName") String bucketName,
                                                 @Parameter(name = "policy", description = "要赋予的策略", in = ParameterIn.QUERY) @RequestParam(value = "policy", required = false) String policy) {
        try {
            this.bucketService.setBucketPolicy(bucketName, policy);
            return successResponse(Boolean.TRUE);
        } catch (Exception e) {
            log.error(e.getMessage());
            return failResponse(Boolean.FALSE, e.getMessage());
        }
    }
}
